package com.nic.view.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;


import com.nic.view.util.DateTimeUtil;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2018/8/17.
 */

public class MonthDateView extends View {
    public static final String LATE = "1";//迟到
    public static final String LEAVE_EARLY = "2";//早退
    public static final String ABSENTEEISM = "3";//旷工
    private static final int NUM_COLUMNS = 7;
    private static final int NUM_ROWS = 6;
    private Paint mPaint;
    private int mDayColor = Color.parseColor("#ffffff");
    private int mSelectDayColor = Color.parseColor("#ffffff");
    private int mSelectBGColor = Color.parseColor("#65CAFF");
    private int mCurrentColor = Color.parseColor("#65CAFF");
    private int mCircleColor = Color.parseColor("#ff0000");
    private int circleRedColor = Color.parseColor("#ff0000");
    private int circleYellowColor = Color.parseColor("#cccc00");
    private int circleGreenColor = Color.parseColor("#009900");
    private int mCurrYear, mCurrMonth, mCurrDay;
    private int mSelYear, mSelMonth, mSelDay;
    private int mColumnSize, mRowSize;
    private DisplayMetrics mDisplayMetrics;
    private int mDaySize = 16;
    private TextView tv_date, tv_week;
    private int weekRow;
    private int[][] daysString;
    private int mCircleRadius = 6;
    private DateClick dateClick;
    private Calendar calendar;
    /**
     * key date
     * key2 state
     */
    private Map<String, String> states = new HashMap<>();

    public void setStates(Map<String, String> states) {
        if (states == null || states.isEmpty()) {
            return;
        }
        this.states = states;
        invalidate();
    }

    private int mMonthDays;//当前选中月多少天

    public int getMonthDays() {
        return mMonthDays;
    }

    public MonthDateView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mDisplayMetrics = getResources().getDisplayMetrics();
        if (calendar == null) {
            calendar = Calendar.getInstance();
        }
        mCurrYear = calendar.get(Calendar.YEAR);
        mCurrMonth = calendar.get(Calendar.MONTH);
        mCurrDay = calendar.get(Calendar.DATE);
        mPaint = new Paint();
        mMonthDays = DateTimeUtil.getMonthDays(mCurrYear, mCurrMonth);
        setSelectYearMonth(mCurrYear, mCurrMonth, mCurrDay);
        // 获取屏幕尺寸
        WindowManager wm = (WindowManager) getContext().getSystemService(
                Context.WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        mCircleRadius = width / 7 / 14;
    }

    public void setCurrCalendar(Calendar currCalendar) {
        this.calendar = currCalendar;
        mCurrYear = calendar.get(Calendar.YEAR);
        mCurrMonth = calendar.get(Calendar.MONTH);
        mCurrDay = calendar.get(Calendar.DATE);
//		setSelectYearMonth(mCurrYear, mCurrMonth, mCurrDay);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    private int measureHeight(int measureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = mDisplayMetrics.widthPixels;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = mDisplayMetrics.widthPixels;//根据自己的需要更改
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        initSize();
        daysString = new int[6][7];
        mPaint.setTextSize(mDaySize * mDisplayMetrics.scaledDensity);
        mPaint.setAntiAlias(true);
        String dayString;
        mMonthDays = DateTimeUtil.getMonthDays(mSelYear, mSelMonth);
        int weekNumber = DateTimeUtil.getFirstDayWeek(mSelYear, mSelMonth);

        for (int day = 0; day < mMonthDays; day++) {
            dayString = (day + 1) + "";
            int column = (day + weekNumber - 1) % 7;
            int row = (day + weekNumber - 1) / 7;
            daysString[row][column] = day + 1;
            int startX = (int) (mColumnSize * column + (mColumnSize - mPaint
                    .measureText(dayString)) / 2);
            int startY = (int) (mRowSize * row + mRowSize / 2 - (mPaint
                    .ascent() + mPaint.descent()) / 2);
            int heightText = (int) (mPaint.descent() - mPaint.ascent());
            int widthText = (int) (mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top);
            int startRecX = mColumnSize * column;
            int startRecY = mRowSize * row;
            int endRecX = startRecX + mColumnSize;
            int endRecY = startRecY + mRowSize;
            RectF rectF = new RectF(startRecX, startRecY, endRecX, endRecY);
//            mCurrMonth == mSelMonth &&
            if (dayString.equals("" + mSelDay)) {
                mPaint.setColor(mSelectBGColor);
//                canvas.drawRect(startRecX, startRecY, endRecX, endRecY, mPaint);
                canvas.drawCircle(rectF.centerX(), rectF.centerY() - heightText / 2, heightText > widthText ? heightText * 2 / 3 : widthText * 2 / 3, mPaint);
                // 记录第几行，即第几周
                weekRow = row + 1;
            }
            // 绘制事务圆形标志
            if (dayString.equals("" + mSelDay)) {
                mPaint.setColor(mSelectDayColor);
            } else if (dayString.equals("" + mCurrDay) && mCurrDay != mSelDay
                    && mCurrMonth == mSelMonth) {
                // 正常月，选中其他日期，则今日为红色
                mPaint.setColor(mCurrentColor);
            } else {
                mPaint.setColor(mDayColor);
            }
            canvas.drawText(dayString, startX, startY - heightText / 2, mPaint);
            if (states.containsKey(getDay(mSelYear, (mSelMonth + 1), day + 1))) {
                String s = states.get(getDay(mSelYear, (mSelMonth + 1), day + 1));
                if (LATE.equals(s)) {
                    mPaint.setColor(circleRedColor);
                } else if (LEAVE_EARLY.equals(s)) {
                    mPaint.setColor(circleYellowColor);
                } else if (ABSENTEEISM.equals(s)) {
                    mPaint.setColor(circleGreenColor);
                } else {
                    s = null;
                }
//                int hText = (int) (mPaint.descent() - mPaint.ascent());
                if (!TextUtils.isEmpty(s)) {
                    canvas.drawCircle(rectF.centerX(),
                            rectF.centerY() + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, mDisplayMetrics)
                            , TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, mDisplayMetrics), mPaint);
                }
            }

            if (tv_date != null) {
                tv_date.setText(mSelYear + "年" + (mSelMonth + 1) + "月");
            }

            if (tv_week != null) {
                tv_week.setText("第" + weekRow + "周");
            }
        }
    }

    private String getDay(int year, int month, int day) {
        return String.format("%s-%s-%s", year, month < 10 ? "0" + month : "" + month, day < 10 ? "0" + day : "" + day);
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }

    private int downX = 0, downY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int eventCode = event.getAction();
        switch (eventCode) {
            case MotionEvent.ACTION_DOWN:
                downX = (int) event.getX();
                downY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                int upX = (int) event.getX();
                int upY = (int) event.getY();
                if (Math.abs(upX - downX) < 10 && Math.abs(upY - downY) < 10) {// 点击事件
                    performClick();
                    doClickAction((upX + downX) / 2, (upY + downY) / 2);
                }
                break;
        }
        return true;
    }

    /**
     * 初始化列宽行高
     */
    private void initSize() {
        mColumnSize = getWidth() / NUM_COLUMNS;
        mRowSize = getHeight() / NUM_ROWS;
    }

    /**
     * 设置年月
     *
     * @param year
     * @param month
     */
    public void setSelectYearMonth(int year, int month, int day) {
        mSelYear = year;
        mSelMonth = month;
        mSelDay = day;
    }

    /**
     * 执行点击事件
     *
     * @param x
     * @param y
     */
    private void doClickAction(int x, int y) {
        int row = y / mRowSize;
        int column = x / mColumnSize;
        setSelectYearMonth(mSelYear, mSelMonth, daysString[row][column]);
        invalidate();
        // 执行activity发送过来的点击处理事件
        if (dateClick != null) {
            dateClick.onClickOnDate();
        }
    }

    /**
     * 左点击，日历向后翻页
     */
    public String onLeftClick() {
        int year = mSelYear;
        int month = mSelMonth;
        int day = mSelDay;
        if (month == 0) {// 若果是1月份，则变成12月份
            year = mSelYear - 1;
            month = 11;
        } else if (DateTimeUtil.getMonthDays(year, month) == day) {
            // 如果当前日期为该月最后一点，当向前推的时候，就需要改变选中的日期
            month = month - 1;
            day = DateTimeUtil.getMonthDays(year, month);
        } else {
            month = month - 1;
        }
        setSelectYearMonth(year, month, day);
        invalidate();
        return getDay(year, month, day);
    }

    /**
     * 右点击，日历向前翻页
     */
    public String onRightClick() {
        int year = mSelYear;
        int month = mSelMonth;
        int day = mSelDay;
        if (month == 11) {// 若果是12月份，则变成1月份
            year = mSelYear + 1;
            month = 0;
        } else if (DateTimeUtil.getMonthDays(year, month) == day) {
            // 如果当前日期为该月最后一点，当向前推的时候，就需要改变选中的日期
            month = month + 1;
            day = DateTimeUtil.getMonthDays(year, month);
        } else {
            month = month + 1;
        }
        setSelectYearMonth(year, month, day);
        invalidate();
        return getDay(year, month, day);
    }

    /**
     * 获取选择的年份
     *
     * @return
     */
    public int getmSelYear() {
        return mSelYear;
    }

    /**
     * 获取选择的月份
     *
     * @return
     */
    public int getmSelMonth() {
        return mSelMonth + 1;
    }

    /**
     * 获取选择的日期
     *
     * @param
     */
    public int getmSelDay() {
        return this.mSelDay;
    }

    /**
     * 普通日期的字体颜色，默认黑色
     *
     * @param mDayColor
     */
    public void setmDayColor(int mDayColor) {
        this.mDayColor = mDayColor;
    }

    /**
     * 选择日期的颜色，默认为白色
     *
     * @param mSelectDayColor
     */
    public void setmSelectDayColor(int mSelectDayColor) {
        this.mSelectDayColor = mSelectDayColor;
    }

    /**
     * 选中日期的背景颜色，默认蓝色
     *
     * @param mSelectBGColor
     */
    public void setmSelectBGColor(int mSelectBGColor) {
        this.mSelectBGColor = mSelectBGColor;
    }

    /**
     * 当前日期不是选中的颜色，默认红色
     *
     * @param mCurrentColor
     */
    public void setmCurrentColor(int mCurrentColor) {
        this.mCurrentColor = mCurrentColor;
    }

    /**
     * 日期的大小，默认18sp
     *
     * @param mDaySize
     */
    public void setmDaySize(int mDaySize) {
        this.mDaySize = mDaySize;
    }

    /**
     * 设置显示当前日期的控件
     *
     * @param tv_date 显示日期
     * @param tv_week 显示周
     */
    public void setTextView(TextView tv_date, TextView tv_week) {
        this.tv_date = tv_date;
        this.tv_week = tv_week;
        invalidate();
    }


    /***
     * 设置圆圈的半径，默认为6
     *
     * @param mCircleRadius
     */
    public void setmCircleRadius(int mCircleRadius) {
        this.mCircleRadius = mCircleRadius;
    }

    /**
     * 设置圆圈的颜色
     *
     * @param mCircleColor
     */
    public void setmCircleColor(int mCircleColor) {
        this.mCircleColor = mCircleColor;
    }

    /**
     * 设置日期的点击回调事件
     *
     * @author shiwei.deng
     */
    public interface DateClick {
        public void onClickOnDate();
    }

    /**
     * 设置日期点击事件
     *
     * @param dateClick
     */
    public void setDateClick(DateClick dateClick) {
        this.dateClick = dateClick;
    }

    /**
     * 跳转至今天
     */
    public void setTodayToView(String today, String format) {
        long milliseconds = DateTimeUtil.setMilliseconds(today, format);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(milliseconds);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        setSelectYearMonth(year, month, day);
        //setSelectYearMonth(mCurrYear, mCurrMonth, mCurrDay);
        invalidate();
    }

    /**
     * 获取年月日
     */

    public String getSelDate() {

        int year = getmSelYear();
        int moth = getmSelMonth();
        int day = getmSelDay();

        String yearStr = "";
        String mothStr = "";
        String dayStr = "";
        // 年
        yearStr = "" + year;
        // 月
        if (moth < 10) {
            mothStr = "-0" + moth;
        } else {
            mothStr = "-" + moth;
        }
        // 日
        if (day < 10) {
            dayStr = "-0" + day;
        } else {
            dayStr = "-" + day;
        }
        // 返回日期
        return yearStr + mothStr + dayStr;

    }

    /**
     * 获取年月
     */

    public String getSelYearAndMonth() {

        int year = getmSelYear();
        int moth = getmSelMonth();

        String yearStr = "";
        String mothStr = "";
        // 年
        yearStr = "" + year;
        // 月
        if (moth < 10) {
            mothStr = "-0" + moth;
        } else {
            mothStr = "-" + moth;
        }
        // 返回日期
        return yearStr + mothStr;

    }

}
